home *** CD-ROM | disk | FTP | other *** search
- -*-text-*-
-
- General decussion of OOP stuff. Add to insideMutt.
-
- Don't do typedefs or structs, go directly to objects.
-
- LISTS and SETS
- ----- --- ----
-
- Definitions:
- LIST: an ordered set of heterogeneous objects.
- OSET: an ordered set of homogeneous objects.
-
- Notes:
- A string is an oset.
- I think that an unordered set is easy to fake from an oset.
- Lists and osets expand/contract as needed.
- ???The first element of a list or oset is numbered 1. This means the
- 0-th element is before the first element in a list. Handy for some
- operations.
- ??? what is the empty set??? []
- Set is a bad name: how about sequence, chain, list, pool, goo???
- Rejected: vector, collection
-
- LIST SYNTAX
- Need an empty set: [], at least for notation.
- Nothing special is needed but it might be nice to add some syntactic
- sugar.
- A oset constant: [1 2 3], the empty set is [].
- Use: (nth-item ["one" "two" "three"] n) (same as switch)
- (foo ["fee" "fie" "foe" "fum"]) (same as (foo (concat ...))
- From CLisp: #(item item ...), #() is empty set. CL book suggests []
- notation is better but users might want to use [] themselves.
-
-
- LIST OPERATIONS
- list/oset operations (foo and bar are lists or sets):
- This is array like notation (always uses an index). Might be pretty
- inefficient/awkward commparded to pointer syntax (ala lisp).
-
- (list type list-name): Create a list.
- All lists are set to the empty list at creation.
- (list string foo): Create a list of lists.
- (list list string foo): Create a list of lists containing strings.
- Kinda like a 2d array.
-
- #if 0 /* this is array syntax, not list syntax */
- (foo n): returns the nth element of foo AS AN atom (if possible)
- eg ("abc" 2) => 'b', ([1 2 3] 2) => 2,
- ([[1] [2 2] [3 3 3]] 2) => [2 2].
- use (n-items). Use (cast-to) if need to atomify (atomize?).
- (foo n object): Replaces the nth element of foo with object.
- eg ("abc" 2 'z') => "azc", ([1 2 3] 2 123) => [1 123 3]
- eg ("abc" 2 "xyz") => ???
- use (replace-item)
- #endif
-
- (foo) returns the contents of foo.
- (foo object [object ...])
- Clears foo, concatanates all the objects and puts them in foo.
- (foo []) Resets foo, ie foo contains the empty list.
- (foo "testing" " 123") => (foo) == "testing 123".
-
- (length-of foo): number of objects in foo.
- (length-of []) => 0.
-
- (n-items foo n [z]):
- Trys to return a list of length z made by coping z elements of foo
- starting at (and including) the nth.
- z defaults to 1.
- ???(n-items foo 1) is the first element of foo.
- If (z <= 0) or (n > (length-of foo)) or (foo == []), returns [].
- If ask for more elements than can get, return as much as can.
- (n-items "123" 2) => "2", (n-items "123" 2 2) => "23"
- (n-items [] n z) => []
- ???If need an atom, use (cast-to ...)
- (concat foo bar): returns a new list.
- (concat [] []) => []
- (concat foo []) => foo
- (concat [] bar) => bar
-
- (add-to foo n object [object ...]):
- Insert object(s) into foo after the nth element.
- If n >= (length foo), this op would be the same as (foo (concat foo
- bar)) and would save some data copies. Maybe just use (add-at
- foo (length foo) bar).
- If (n < "first element"), prepend ie same as (foo (concat bar foo))
- (add-to [] n bar) => ???error, can't save result or just stash in
- RV ie same as (concat [] bar).
- eg (add-to "123" 1 "9") => "1923"
- (remove-items foo n [z]): Remove z items from foo starting at
- (including) n. z defaults to 1. This could be implemented as
- (foo (n-items foo 1 (- n 1)) (n-items foo (+ n 1) (length foo))).
- If (n >= (length foo)) => foo
- If try to remove more elements than in foo, return [].
- If (z <= 0) return foo.
- (remove-items [] n [z]): [].
- (replace-items foo n z object [object ...])
- Same as (remove-items foo n z)(add-to foo n-1 object [object ...])
-
- Misc: These could be Mutt routines.
- (is-in foo object [n [m]]) ?? (in-list)
- Returns <something> if object is in list foo.
- Return: TRUE/FALSE or n/-1
- Start at n, end at m.
- ??? what about arb objects, how compare?
- (apply-to foo Mutt-fcn): For every item in foo, call Mutt-fcn and
- pass it the nth item of foo.
-
- Problems:
- Lists or osets of lists or osets.
- How do I (joe mutt programmer) know what (nth-item foo-list n) is? Is
- there a (type foo)? What happens when foo is a user defined object?
- That would mean a central (MM) dictionary of tuples: (object type
- #, object description). Many disjoint programs might share objects
- so the compiler would have to generate code that registered an
- object and stashed the type so it could be used for type checking,
- etc. 1 byte is probably not enough for all the possible types.
- This would be a pretty cool concept - ME could generate types for
- buffer/bag/region stats, etc so I could do better type checking.
- (msg) would work automagically with objects. On the other hand it
- might a be a real drag to implement, slow things down and use up
- lots more space. If I don't implement this, JP would have to know
- (by putting a type field in the object) how to figure out the object
- type. Maybe the best idea is just punt lists and stick with osets.
-
-
-
- OBJECTS
- -------
-
- (object
- DATA
- {
- }
- CREATE ;; constructer
- {
- }
- FREE ;; destructer
- {
- }
- methods
- overloading
- ...
- }
-
- A struct is just the data subset of this.
-
- Object data is built on top of basic/atomic Mutt types: NUMBER (byte,
- int, INT), STRING, ?VOID, REAL, BOOLEAN, BLOB, FCNPTR, LIST, array.
-
- PROBLEMS
- --------
- How manage types that are:
- - fixed length, fixed object size (NUMBER, REAL, BOOLEAN)
- - fixed length, unknown object size (FCNPTR)
- - unknown length, fixed object size (STRING)
- - unknown length, unknown object size (LIST)
- - objects that are built from the above types
- How store, get and set.
-
- What about:
- - (loc object): How do I type check?
- - How do I type check objects? do I need to?
-
-
- EXAMPLES
- --------
-
- (object Buffer
- DATA
- {
- (int buffer-id)
- }
- CREATE ;; constructer
- {
- (buffer-id (create-buffer))
- }
- FREE ;; destructer
- {
- (free-buffer buffer-id)
- }
- info
- {
- }
- methods
- overloading
- ...
- }
-
- (object Mark
- DATA
- {
- (int mark-id)
- }
- CREATE ;; constructer
- {
- (mark-id (create-mark))
- }
- FREE ;; destructer
- {
- (free-mark mark-id)
- }
- methods
- overloading
- ...
- }
-
- mark-rings
-
-
- IMPLEMENTATIONS
- ---------------
-
- Smalltalk Model
-
- code varables object table objects
- Var : contents index : pointer address : contents
- list a : 3 1 : aaa
- string b : 1 2 : xxx
- 3 : bbb
-
-
- Each object varible in the code contains a 2 byte object number that is
- an index into the object table. The object table contains pointers to
- the actual objects.
-
- Get: The address of object n is: object-table[n]
- Set:
- Allocate:
- Look though object table until find an index that is unused.
- If none: GC.
- Repeat lookup.
- If object table full (GC didn't free anything):
- Expand object table.
- If can't: fail.
- Return index.
- GC:
- (1) Mark all entries in the object table as dead.
- (2) For all live code object variables, mark object-table[var-index]
- as live.
- (3) Free all objects marked as dead in the object table.
-
- Variation 1 on the Smalltalk model:
- Move object table into the objects.
- - Don't use a object table.
- - Each object is linked to the next object.
- - Vars contain pointers to the actual objects.
- Pros:
- - Less to think about and manage.
- - Object look up is faster.
- Cons:
- - Probably uses more space.
-
- Variation 2:
- Copy objects instead of mark/sweep:
- Look though object table
- If object in use, copy it to a new list
- Free all objects in the orginal list.
-
-
- When garbage collect:
- - When malloc fails
- - When a program is done running
- - When a block is freed
-